package com.coldchain.common.util;

import com.coldchain.common.exception.base.BusinessException;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

/**
 * @ClassName CollectFeeUtils
 * @Description TODO
 * @Author fangliai
 * @Date 2018/9/20 10:56
 * @Vesion 1
**/
public class CollectFeeUtils {
    private Logger log= LoggerFactory.getLogger(CollectFeeUtils.class);
    private Binding binding;
    private  Numerical numerical;

    public CollectFeeUtils(Numerical numerical) {
        this.binding = new Binding();
        this.numerical=numerical;
        addExpression(Expression.DISCOUNTS,numerical.discounts>0?numerical.discounts/100:1);
        addExpression(Expression.USE,numerical.usePrice);
    }

    /**
     * 添加表达式
     * @param expression
     * @param value
     * @return
     */
    private   void addExpression(Expression expression,double value){
         binding.setVariable(expression.name(),value);

    }

    /**
     * 计算公式
     * @return
     * @throws BusinessException
     */
    public  double compute(double orderKm,int delivery)throws BusinessException {
        if(orderKm>numerical.getEffectiveKm()){
            addExpression(Expression.EXCEED,(orderKm-numerical.getEffectiveKm()*numerical.getExceedPrice()));
        }else {
            addExpression(Expression.EXCEED,0);
        }
        addExpression(Expression.DELIVERY,delivery);

        GroovyShell shell = new GroovyShell(binding);
        try{
            Object result = shell.evaluate(numerical.getExpression());
            return  Double.valueOf(result.toString());
        }catch (Exception e){
             log.error("公式计算错误 error:"+e.getMessage());
             throw  new BusinessException("公式计算错误,请检查是否正确配制表达式:"+numerical.getExpression());
        }
    }

   public static enum  Expression{
        /**
         * 起步价
         */
        USE,
        /**
         * 配送点
         */
        DELIVERY,
        /**
         * 优惠
         */
        DISCOUNTS,
        /**
         * 超出收费
         */
        EXCEED
    }

   public static class Numerical  implements Serializable {
       private  double exceedPrice;
       private  double usePrice;
       private  int discounts;
       private  String expression;
       private  int effectiveKm;
        public double getExceedPrice() {
            return exceedPrice;
        }

        public void setExceedPrice(double exceedPrice) {
            this.exceedPrice = exceedPrice;
        }
        public double getUsePrice() {
            return usePrice;
        }
        public void setUsePrice(double usePrice) {
            this.usePrice = usePrice;
        }

        public int getDiscounts() {
            return discounts;
        }

        public void setDiscounts(int discounts) {
            this.discounts = discounts;
        }

        public String getExpression() {
            return expression;
        }

        public void setExpression(String expression) {
            this.expression = expression;
        }

        public int getEffectiveKm() {
            return effectiveKm;
        }

        public void setEffectiveKm(int effectiveKm) {
            this.effectiveKm = effectiveKm;
        }
    }
}
